package com.example.myremotecontroller;

import android.content.Context;

import com.inuker.bluetooth.library.BluetoothClient;
import com.inuker.bluetooth.library.beacon.Beacon;
import com.inuker.bluetooth.library.connect.request.BleWriteNoRspRequest;
import com.inuker.bluetooth.library.connect.response.BleConnectResponse;
import com.inuker.bluetooth.library.connect.response.BleNotifyResponse;
import com.inuker.bluetooth.library.connect.response.BleWriteResponse;
import com.inuker.bluetooth.library.model.BleGattProfile;
import com.inuker.bluetooth.library.search.SearchRequest;
import com.inuker.bluetooth.library.search.SearchResult;
import com.inuker.bluetooth.library.search.response.SearchResponse;
import com.inuker.bluetooth.library.utils.BluetoothLog;
import com.inuker.bluetooth.library.utils.ByteUtils;
import com.inuker.bluetooth.library.utils.UUIDUtils;

import java.util.UUID;

import static com.inuker.bluetooth.library.Code.REQUEST_SUCCESS;

public class CarBLE {
    private BluetoothClient bleClient_;
    private String targetMac_ = null;
    private UUID serviceUUID_;
    private UUID writeCharacterUUID_;
    private UUID notifyCharacterUUID_;

    public CarBLE(Context context){
        bleClient_ = new BluetoothClient(context);
        serviceUUID_ = UUIDUtils.makeUUID(0xA002);
        writeCharacterUUID_ = UUIDUtils.makeUUID(0xC304);
        notifyCharacterUUID_ = UUIDUtils.makeUUID(0xC305);
    }

    public void connectTarget()
    {
        SearchRequest req = new SearchRequest.Builder()
                .searchBluetoothLeDevice(5000)
                .build();

        bleClient_.search(req, new SearchResponse() {
            @Override
            public void onSearchStarted() {

            }

            @Override
            public void onDeviceFounded(SearchResult device) {
                Beacon beacon = new Beacon(device.scanRecord);
                BluetoothLog.v(String.format("beacon for %s\n%s", device.getAddress(), beacon.toString()));
                String bleId = ByteUtils.byteToString(beacon.mBytes);//= 0201060A0941695468696E6B6572
                if(bleId.endsWith("41695468696E6B6572")) // = ASCII("AiThinker")
                {
                    targetMac_ = device.getAddress();
                    bleClient_.stopSearch();
                }
            }

            @Override
            public void onSearchStopped() {

            }

            @Override
            public void onSearchCanceled() {
                // 当搜索被主动取消, 则为找到目标
                bleClient_.connect(targetMac_, new BleConnectResponse() {
                    @Override
                    public void onResponse(int code, BleGattProfile data) {
                        if(code == REQUEST_SUCCESS)
                        {
                            BluetoothLog.i("BLE connected.");
                            bleClient_.notify(targetMac_, serviceUUID_, notifyCharacterUUID_, new BleNotifyResponse() {
                                @Override
                                public void onNotify(UUID service, UUID character, byte[] value) {

                                }
                                @Override
                                public void onResponse(int code) {
                                    if(code == REQUEST_SUCCESS) {
                                        BluetoothLog.i("bleClient_.notify success.");

                                    }else{
                                        BluetoothLog.e(String.format("bleClient_.notify failed. code=%d.", code));
                                    }
                                }
                            });
                        }else{
                            BluetoothLog.e(String.format("connect failed. code=%d", code));
                        }
                    }
                });
            }
        });
    }

    public void sendBytes(final byte[] bytes)
    {
        BluetoothLog.v(String.format("send Bytes:%s", ByteUtils.byteToString(bytes)));
        bleClient_.write(targetMac_, serviceUUID_, writeCharacterUUID_, bytes, new BleWriteResponse(){
            @Override
            public void onResponse(int code){
                if(code == REQUEST_SUCCESS)
                {
                    BluetoothLog.v("write success.");
                }else{
                    BluetoothLog.e(String.format("write failed. code=%d.", code));
                }
            }
        } );
    }

    // v:[7FFF, -8001]
    // a:[7FFF, -8001]
    public void sendMoveCmd(int v, int a)
    {
        //                   0     1     2    3  4  5  6  7
        byte[] cmd = {(byte)0xA5, 0x06, 0x01, 0, 0, 0, 0, 0};
        cmd[3] = (byte) ((v & 0xFF00) >> 8);
        cmd[4] = (byte) (v & 0xFF);
        cmd[5] = (byte) ((a & 0xFF00) >> 8);
        cmd[6] = (byte) (a & 0xFF);
        // byte[] cmd2 = {(byte)0xA5, 0x06, 0x01, 0x7F, (byte) 0xFF, 0x00, 0x00, 0};
        cmd[7] = calcCRC8(cmd,2, 6 - 1);
        sendBytes(cmd);
    }

    public byte calcCRC8(byte[] bytes, int start ,int len)
    {
        int crc = 0;
        int k = start;
        int i,j;
        for (j=len; j > 0; j--, k++)
        {
            crc ^= (bytes[k] << 8);
            for (i = 8; i > 0; i--)
            {
                if((crc & 0x8000) != 0)
                    crc ^= (0x07 << 7);

                crc <<= 1;
                crc &= 0xFFFF;
            }
        }
        return (byte)(crc >> 8);
    }
}
